package com.ruoyi.StarStudio.MQTT;

import com.ruoyi.StarStudio.MQTT.Config.MqttConfig;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component
public class EmqClient {

    private static final Logger log = LoggerFactory.getLogger(EmqClient.class);

    private IMqttClient mqttClient;

    @Autowired
    private MqttCallback mqttCallback;

    @Autowired
    private MqttConfig mqttConfig;

    @PostConstruct
    public void init(){
        MqttClientPersistence mqttClientPersistence = new MemoryPersistence();
        try {
            mqttClient = new MqttClient(mqttConfig.getBrokerUrl(),mqttConfig.getClientId(),mqttClientPersistence);
        } catch (MqttException e) {
            //e.printStackTrace();
            log.error("初始化客户端mqttClient对象失败，errormsg={},brokerUrl={},clientId={}",e.getMessage(),mqttConfig.getBrokerUrl(),mqttConfig.getClientId());
        }
    }

    /**
     * 连接broker服务端
     * @param username
     * @param password
     */
    public void connect(String username,String password){
        MqttConnectOptions options = new MqttConnectOptions();
        options.setAutomaticReconnect(true);
        options.setUserName(mqttConfig.getUsername());
        options.setPassword(mqttConfig.getPassword().toCharArray());
        options.setCleanSession(true);
        mqttClient.setCallback(mqttCallback);
        try {
            mqttClient.connect(options);
            log.info("连接MQTT客户端成功");
        } catch (MqttException e) {
            log.error("mqtt客户端连接服务端失败，失败原因{}",e.getMessage());
        }
    }

    /**
     * 断开连接
     */
    @PreDestroy
    public void disconnect(){
        try {
            mqttClient.disconnect();
        } catch (MqttException e) {
            log.error("mqtt客户端连接服务器失败，失败原因{}",e.getMessage());
        }
    }

    /**
     * 重新连接
     */
    public void reconnect(){
        try {
            mqttClient.reconnect();
            log.info("已重新连接服务端");
        } catch (MqttException e) {
            log.error("重连失败，失败原因{}",e.getMessage());
        }
    }

    /**
     * 发布消息
     * @param topic
     * @param msg
     * @param qosEnum
     * @param retain
     */
    public void publish(String topic, String msg, QosEnum qosEnum, boolean retain){
        MqttMessage mqttMessage = new MqttMessage();
        mqttMessage.setPayload(msg.getBytes());
        mqttMessage.setQos(qosEnum.value());
        mqttMessage.setRetained(retain);
        try {
            mqttClient.publish(topic,mqttMessage);
        } catch (Exception e) {
            log.error("发布消息失败，errormsg={},topic={},msg={},qos={},retain={}",e.getMessage(),topic,msg,qosEnum.value(),retain);
        }
    }

    /**
     * 订阅主题
     * @param topicFilter
     * @param qosEnum
     */
    public void subscribe(String topicFilter,QosEnum qosEnum){
        try {
            mqttClient.subscribe(topicFilter,qosEnum.value());
            log.info("已订阅主题{}",topicFilter);
        } catch (MqttException e) {
            log.error("订阅主题失败，erormsg={},topicFilter={},qos={}",e.getMessage(),topicFilter,qosEnum.value());
        }
    }

    /**
     * 取消订阅
     * @param topicFilter
     */
    public void unsubscribe(String topicFilter){
        try {
            mqttClient.unsubscribe(topicFilter);
        } catch (MqttException e) {
            log.error("取消订阅失败，errormsg={},topicfilter={}",e.getMessage(),topicFilter);
        }
    }
}
